--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Node / ReticulumProjects / MeshChatX.git / files / meshchatx / src / frontend / js / webAudioMicPermission.js
Displaying Raw • Download
meshchatx/src/frontend/js/webAudioMicPermission.js HEAD (2bf00cb3) Text, 3.08 KB
T8b949e// SPDX-License-Identifier: 0BSD
T8b949e/**
* Browser microphone permission helpers for the LXST web audio bridge.
*
* Chromium and Brave only show a getUserMedia prompt from a user gesture,
* on a secure context, and with unconstrained { audio: true } as the first
* call. Processing flags or deviceId.exact before permission often yield
* NotFoundError with no dialog, especially on Brave Shields and on
* self-signed HTTPS origins the user clicked through.
*/
Tff7b72export Tff7b72const Te6edf3WEB_AUDIO_MIC_TOAST_KEY Tff7b72= Ta5d6ff"call-web-audio-mic"Tb4b4b4;
Tff7b72export Tff7b72function Te6edf3isSecureMediaContextTb4b4b4(Te6edf3win Tff7b72= Tffa657globalThisTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3winTff7b72?Tb4b4b4.Te6edf3isSecureContext Tff7b72!== Tff7b72falseTb4b4b4;
Tb4b4b4}
Tff7b72export Tff7b72function Te6edf3isBraveBrowserTb4b4b4(Te6edf3nav Tff7b72= Tffa657globalThisTb4b4b4.Te6edf3navigatorTb4b4b4) Tb4b4b4{
Tff7b72return Tffa657BooleanTb4b4b4(Te6edf3navTff7b72?Tb4b4b4.Te6edf3braveTb4b4b4) Tff7b72|| Ta5d6ff/Brave/iTb4b4b4.Te6edf3testTb4b4b4(Te6edf3navTff7b72?Tb4b4b4.Te6edf3userAgent Tff7b72|| Ta5d6ff""Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72export Tff7b72function Te6edf3isMeshChatXAndroidTb4b4b4(Te6edf3win Tff7b72= Tffa657globalThisTb4b4b4) Tb4b4b4{
Tff7b72return Tb4b4b4(
Tffa657BooleanTb4b4b4(Te6edf3winTff7b72?Tb4b4b4.Te6edf3MeshChatXAndroidTb4b4b4) Tff7b72&&
Tff7b72typeof Te6edf3winTb4b4b4.Te6edf3MeshChatXAndroidTb4b4b4.Te6edf3getPlatform Tff7b72=== Ta5d6ff"function" Tff7b72&&
Te6edf3winTb4b4b4.Te6edf3MeshChatXAndroidTb4b4b4.Te6edf3getPlatformTb4b4b4(Tb4b4b4) Tff7b72=== Ta5d6ff"android"
Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72export Tff7b72async Tff7b72function Te6edf3queryMicrophonePermissionStateTb4b4b4(Te6edf3nav Tff7b72= Tffa657globalThisTb4b4b4.Te6edf3navigatorTb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Tff7b72const Te6edf3perms Tff7b72= Te6edf3navTff7b72?Tb4b4b4.Te6edf3permissionsTb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3perms Tff7b72|| Tff7b72typeof Te6edf3permsTb4b4b4.Te6edf3query Tff7b72!== Ta5d6ff"function"Tb4b4b4) Tb4b4b4{
Tff7b72return Tff7b72nullTb4b4b4;
Tb4b4b4}
Tff7b72const Te6edf3status Tff7b72= Tff7b72await Te6edf3permsTb4b4b4.Te6edf3queryTb4b4b4(Tb4b4b4{ Te6edf3nameTff7b72: Ta5d6ff"microphone" Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3statusTff7b72?Tb4b4b4.Te6edf3state Tff7b72|| Tff7b72nullTb4b4b4;
Tb4b4b4} Tff7b72catch Tb4b4b4{
Tff7b72return Tff7b72nullTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72export Tff7b72function Te6edf3classifyGetUserMediaErrorTb4b4b4(Te6edf3errorTb4b4b4, Tb4b4b4{ Te6edf3permissionState Tff7b72= Tff7b72nullTb4b4b4, Te6edf3isBrave Tff7b72= Tff7b72false Tb4b4b4} Tff7b72= Tb4b4b4{Tb4b4b4}Tb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3name Tff7b72= Te6edf3errorTff7b72?Tb4b4b4.Te6edf3nameTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3name Tff7b72=== Ta5d6ff"NotAllowedError" Tff7b72|| Te6edf3name Tff7b72=== Ta5d6ff"SecurityError"Tb4b4b4) Tb4b4b4{
Tff7b72return Ta5d6ff"call.microphone_permission_denied"Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3name Tff7b72=== Ta5d6ff"NotFoundError" Tff7b72|| Te6edf3name Tff7b72=== Ta5d6ff"OverconstrainedError"Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3permissionState Tff7b72=== Ta5d6ff"denied"Tb4b4b4) Tb4b4b4{
Tff7b72return Ta5d6ff"call.microphone_permission_denied"Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3permissionState Tff7b72=== Ta5d6ff"granted"Tb4b4b4) Tb4b4b4{
Tff7b72return Ta5d6ff"call.no_audio_input_found"Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3isBraveTb4b4b4) Tb4b4b4{
Tff7b72return Ta5d6ff"call.microphone_prompt_blocked"Tb4b4b4;
Tb4b4b4}
Tff7b72return Ta5d6ff"call.microphone_permission_needed"Tb4b4b4;
Tb4b4b4}
Tff7b72return Ta5d6ff"call.web_audio_not_available"Tb4b4b4;
Tb4b4b4}
Tff7b72export Tff7b72async Tff7b72function Te6edf3promptMicrophoneAccessTb4b4b4(Te6edf3mediaDevicesTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3mediaDevices Tff7b72|| Tff7b72typeof Te6edf3mediaDevicesTb4b4b4.Te6edf3getUserMedia Tff7b72!== Ta5d6ff"function"Tb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3err Tff7b72= Tff7b72new Tf85149ErrorTb4b4b4(Ta5d6ff"navigator.mediaDevices is unavailable"Tb4b4b4)Tb4b4b4;
Te6edf3errTb4b4b4.Te6edf3name Tff7b72= Ta5d6ff"NotSupportedError"Tb4b4b4;
Tff7b72throw Te6edf3errTb4b4b4;
Tb4b4b4}
Tff7b72const Te6edf3stream Tff7b72= Tff7b72await Te6edf3mediaDevicesTb4b4b4.Te6edf3getUserMediaTb4b4b4(Tb4b4b4{ Te6edf3audioTff7b72: Tff7b72true Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3tracks Tff7b72= Tff7b72typeof Te6edf3streamTff7b72?Tb4b4b4.Te6edf3getTracks Tff7b72=== Ta5d6ff"function" Tff7b72? Te6edf3streamTb4b4b4.Te6edf3getTracksTb4b4b4(Tb4b4b4) Tff7b72: Tb4b4b4[Tb4b4b4]Tb4b4b4;
Te6edf3tracksTb4b4b4.Te6edf3forEachTb4b4b4(Tb4b4b4(Te6edf3trackTb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72try Tb4b4b4{
Te6edf3trackTb4b4b4.Te6edf3stopTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72catch Tb4b4b4{
T8b949e// ignore
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72return Tff7b72trueTb4b4b4;
Tb4b4b4}
Tff7b72export Tff7b72async Tff7b72function Te6edf3promptMicrophoneAccessFromWindowTb4b4b4(Te6edf3win Tff7b72= Tffa657globalThisTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3isMeshChatXAndroidTb4b4b4(Te6edf3winTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Tff7b72trueTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3isSecureMediaContextTb4b4b4(Te6edf3winTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3err Tff7b72= Tff7b72new Tf85149ErrorTb4b4b4(Ta5d6ff"insecure context"Tb4b4b4)Tb4b4b4;
Te6edf3errTb4b4b4.Te6edf3name Tff7b72= Ta5d6ff"SecurityError"Tb4b4b4;
Tff7b72throw Te6edf3errTb4b4b4;
Tb4b4b4}
Tff7b72const Te6edf3mediaDevices Tff7b72= Te6edf3winTff7b72?Tb4b4b4.Te6edf3navigatorTff7b72?Tb4b4b4.Te6edf3mediaDevicesTb4b4b4;
Tff7b72return Te6edf3promptMicrophoneAccessTb4b4b4(Te6edf3mediaDevicesTb4b4b4)Tb4b4b4;
Tb4b4b4}
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────